﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
using System.Reflection;

namespace CNative
{
    public static partial class Utils
    {

        /// <summary>
        /// DataTable转List
        /// </summary>
        /// <typeparam name="T">转换类型</typeparam>
        /// <param name="dt">数据源</param>
        /// <returns></returns>
        public static List<T> DataTableToList<T>(this DataTable dt) where T : class, new()
        {

            return Utilities.FuncTable2Entity.DataTable2List<T>(dt);
        }

        /// <summary>
        ///将DataTable转换为标准的CSV字符串
        /// </summary>
        /// <param name="dt">数据表</param>
        /// <returns>返回标准的CSV</returns>
        public static string ToCsvStr(this DataTable dt)
        {
            //以半角逗号（即,）作分隔符，列为空也要表达其存在。
            //列内容如存在半角逗号（即,）则用半角引号（即""）将该字段值包含起来。
            //列内容如存在半角引号（即"）则应替换成半角双引号（""）转义，并用半角引号（即""）将该字段值包含起来。
            StringBuilder sb = new StringBuilder();
            DataColumn colum;
            foreach (DataRow row in dt.Rows)
            {
                for (int i = 0; i < dt.Columns.Count; i++)
                {
                    colum = dt.Columns[i];
                    if (i != 0) sb.Append(",");
                    if (colum.DataType == typeof(string) && row[colum].ToString().Contains(","))
                    {
                        sb.Append("\"" + row[colum].ToString().Replace("\"", "\"\"") + "\"");
                    }
                    else sb.Append(row[colum].ToString());
                }
                sb.AppendLine();
            }

            return sb.ToString();
        }

        /// <summary>
        /// 转换为一个DataTable
        /// </summary>
        /// <typeparam name="TResult"></typeparam>
        ///// <param name="ilist"></param>
        /// <returns></returns>
        public static DataTable ToDataTable<TResult>(this IEnumerable<TResult> ilist) where TResult : class
        {
            //创建属性的集合
            var pList = new List<System.Reflection.PropertyInfo>();
            //获得反射的入口
            var type = typeof(TResult);
            DataTable dt = new DataTable(type.Name);
            //把所有的public属性加入到集合 并添加DataTable的列
            System.Array.ForEach<System.Reflection.PropertyInfo>(type.GetProperties(), p =>
            {
                if (p.CanRead && p.PropertyType.IsValueType || p.PropertyType==typeof(string))
                {
                    if (p.PropertyType.IsGenericType)
                    {
                        pList.Add(p);
#if NET40
                        dt.Columns.Add(p.Name, p.PropertyType);
#else
                        dt.Columns.Add(p.Name, p.PropertyType.GenericTypeArguments[0]);
#endif
                    }
                    else
                    {
                        pList.Add(p);
                        dt.Columns.Add(p.Name, p.PropertyType);
                    }
                }
            });
            ilist.ForEach(item =>
            {
                //创建一个DataRow实例
                DataRow row = dt.NewRow();
        
                //给row 赋值
                pList.ForEach(p =>
                {
                    var proValue = p.GetValue(item, null);
                    if (proValue == null)
                        row[p.Name] = DBNull.Value;
                    else
                        row[p.Name] = p.GetValue(item, null);
                });
                //加入到DataTable
                dt.Rows.Add(row);
            });
            dt.AcceptChanges();
            return dt;
        }
    }
}
